import math
import os

import pandas as pd
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from qgis._core import QgsVectorLayer, QgsProject, QgsLineSymbol, QgsSingleSymbolRenderer, QgsVectorFileWriter, \
    QgsMarkerSymbol, QgsRasterMarkerSymbolLayer, QgsSvgMarkerSymbolLayer, QgsPointXY, QgsGeometry, QgsField, QgsFeature, \
    QgsSimpleMarkerSymbolLayer

from qgis._gui import QgsVertexMarker
from map.tool import RouteMapTool
from PyQt5.QtCore import Qt, QTimer, QVariant, QDateTime, QObject, QPoint, QPointF


class Route(QObject):
    def __init__(self, canvas):
        super().__init__()
        # 初始化航线图层
        self.canvas = canvas
        self.route_layer = None
        self.is_drawing = False
        self.current_ship_index = 0
        self.ship_layer = None
        #self.__clock()
        self.ship_timer = QTimer(self)
        self.ship_timer.timeout.connect(self.update_ship_position)

    def print(self):
        print("测试")

    def _check_chart_loaded(self):
        """检查是否已加载有效海图图层"""
        return any(
            layer.name().upper() in ["M_COVR", "DEPARE", "LNDARE"]
            for layer in QgsProject.instance().mapLayers().values()
        )

    def start_drawing(self):
        """开始绘制航线"""
        if not self._check_chart_loaded():
            QMessageBox.warning(None, "警告", "请先加载海图数据！")
            return
        print("开始绘制航线模式")
        self.is_drawing = True

        # 创建临时航线图层
        self.route_layer = QgsVectorLayer("LineString?crs=EPSG:4326", "临时航线", "memory")
        QgsProject.instance().addMapLayer(self.route_layer, False)

        # 设置样式：红色虚线
        symbol = QgsLineSymbol.createSimple({
            'color': '255,0,0,200',  # 红色
            'width': '2',  # 2像素宽
            'style': 'dash'  # 虚线
        })
        self.route_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        # 添加到图层树
        root = QgsProject.instance().layerTreeRoot()
        route_group = root.findGroup("航线")
        if not route_group:
            route_group = root.addGroup("航线")
        route_group.addLayer(self.route_layer)

        # 连接画布点击事件
        self.map_tool = RouteMapTool(self.canvas, self.route_layer, self)
        self.canvas.setMapTool(self.map_tool)

    def exit_drawing(self):
        if self.is_drawing:
            if hasattr(self, 'map_tool'):
                self.canvas.unsetMapTool(self.map_tool)
            self.is_drawing = False
            print("退出航线绘制模式")
    def save_route(self):
        """保存当前航线"""
        if not self.route_layer or self.route_layer.featureCount() == 0:
            print("没有可保存的航线")
            QMessageBox.warning(None, "保存失败", "当前没有可保存的航线")
            return

        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存航线", "", "GeoJSON 文件 (*.geojson);;所有文件 (*)"
        )

        if file_path:
            # 确保文件扩展名正确
            if not file_path.endswith('.geojson'):
                file_path += '.geojson'

            # 保存为GeoJSON
            error = QgsVectorFileWriter.writeAsVectorFormat(
                self.route_layer,
                file_path,
                "utf-8",
                self.route_layer.crs(),
                "GeoJSON"
            )

            if error[0] == QgsVectorFileWriter.NoError:
                print(f"航线已保存至: {file_path}")
                QMessageBox.information(None, "保存成功", f"航线已成功保存至:\n{file_path}")
            else:
                print(f"保存失败: {error[1]}")
                QMessageBox.critical(None, "保存失败", f"保存航线时出错:\n{error[1]}")

    def clear_route(self):
        """清除当前航线"""
        if self.route_layer:
            # 退出绘制模式
            self.exit_drawing()

            # 从图层树中移除
            root = QgsProject.instance().layerTreeRoot()
            route_group = root.findGroup("航线")
            if route_group:
                route_group.removeLayer(self.route_layer)

            # 从项目中移除图层
            QgsProject.instance().removeMapLayer(self.route_layer.id())
            self.route_layer = None

            print("航线已清除")
            QMessageBox.information(None, "清除航线", "当前航线已成功清除")

    def add_ship_route(self):
        if self.ship_layer:
            print("ship_layer",self.ship_layer)
            QMessageBox.warning(None, "清除航线", "添加新航线前请先清除旧航线")
            return
            #self.clear_ship_route()
        self.ship_timer.stop()
        if not self.load_ship_positions_from_excel():  # 读取失败则退出
            return
        # 重置位置索引并启动定时器
        self.current_ship_index = 0
        self.ship_timer.start(1000)  # 1秒间隔
    def load_ship_positions_from_excel(self):

        if not self._check_chart_loaded():
            QMessageBox.warning(None, "警告", "请先加载海图数据！")
            return
        parent = self.canvas.parent() if self.canvas.parent() else None
        file_path, _ = QFileDialog.getOpenFileName(None, "导入船舶轨迹Excel文件", "", "Excel文件 (*.xlsx *.xls);;所有文件 (*)")
        if not file_path:  # 用户取消选择
            return False

        try:
            # 读取Excel文件（确保安装openpyxl引擎）
            df = pd.read_excel(file_path, engine='openpyxl')

            # 自动检测中英文列名
            lon_col = next(
                (col for col in df.columns
                 if any(kw in col.lower() for kw in ["lon", "longitude", "经度"])),
                None
            )
            print("lon_col",lon_col)
            lat_col = next(
                (col for col in df.columns
                 if any(kw in col.lower() for kw in ["lat", "latitude", "纬度"])),
                None
            )
            print("lat_col", lat_col)
            heading_col = next(
                (col for col in df.columns
                 if any(kw in col.lower() for kw in ["heading", "艏向", "艏向角"])),
                None
            )
            print("heading_col", heading_col)
            if not all([lon_col, lat_col, heading_col]):
                QMessageBox.critical(None, "错误", "Excel必须包含经度、纬度和艏向列")
                return False

            # 过滤无效坐标并转换为QgsPointXY
            valid_coords = df[(~df[lon_col].isna()) & (~df[lat_col].isna()) & (~df[heading_col].isna())]
            self.ship_positions = [
              QgsPointXY(lon, lat)
               for lon, lat in zip(valid_coords[lon_col], valid_coords[lat_col])
               if not (math.isnan(lon) or math.isnan(lat))
            ]

            # 存储位置和艏向
            self.ship_positions = []
            self.ship_headings = []
            for _, row in df.iterrows():
                if not (pd.isna(row[lon_col]) or pd.isna(row[lat_col])):
                    self.ship_positions.append(QgsPointXY(row[lon_col], row[lat_col]))
                    # 默认艏向为0(北)如果缺失
                    heading = 0 if pd.isna(row[heading_col]) else float(row[heading_col])
                    self.ship_headings.append(heading)
            return True

        except Exception as e:
            print(f"Excel解析失败: {str(e)}")
            QMessageBox.critical(
                None,  # 使用self作为父窗口
                "错误",
                f"文件读取失败:\n{str(e)}"
            )
            return False

    def update_ship_position(self):
        if self.current_ship_index >= len(self.ship_positions):
            self.ship_timer.stop()
            return

        # 清除旧点图层（保留轨迹线图层）
        project_root = os.path.dirname(os.path.dirname(__file__))
        ship_image_path = os.path.join(project_root, "resources", "trangle.png")
        #print("ship_image_path",ship_image_path)
        try:
            if not os.path.exists(ship_image_path):
              QMessageBox.critical(None, "错误", f"图标文件不存在:\n{ship_image_path}")
              return
            if self.ship_layer:
                QgsProject.instance().removeMapLayer(self.ship_layer)

            # 创建新点图层（当前位置）
            self.ship_layer = QgsVectorLayer("Point?crs=EPSG:4326", "船舶位置", "memory")
            provider = self.ship_layer.dataProvider()
            provider.addAttributes([
                QgsField("time", QVariant.String),  # 添加长度限制（如字符串长度）
                QgsField("heading", QVariant.Double)
            ])
            self.ship_layer.updateFields()

            # 添加当前船舶位置
            current_pos = self.ship_positions[self.current_ship_index]
            current_heading = self.ship_headings[self.current_ship_index]
            feat = QgsFeature()
            feat.setGeometry(QgsGeometry.fromPointXY(current_pos))
            feat.setAttributes([
                QDateTime.currentDateTime().toString("hh:mm:ss"),
                current_heading
            ])
            provider.addFeatures([feat])

            # 设置船舶图标样式（替换为您的图标路径）
            symbol = QgsMarkerSymbol.createSimple({'color': '255,0,0,0'})
            symbol_layer = QgsRasterMarkerSymbolLayer(ship_image_path)
            symbol_layer.setSize(5)
            symbol_layer.setAngle(current_heading)
            symbol_layer.setOffset(QPoint(0, 0))
            symbol.changeSymbolLayer(0, symbol_layer)
            # if self.ship_layer is not None:
            #     print(self.ship_layer.renderer)
            # else:
            #     print("ship_layer为 None，无法访问 renderer")
            self.ship_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

            # 添加到图层组
            QgsProject.instance().addMapLayer(self.ship_layer, False)
            root = QgsProject.instance().layerTreeRoot()
            ship_group = root.findGroup("船舶标记") or root.addGroup("船舶标记")
            ship_group.addLayer(self.ship_layer)

            # 更新轨迹线图层（新增部分）
            if not hasattr(self, 'trail_layer'):
                self.trail_layer = QgsVectorLayer("LineString?crs=EPSG:4326", "船舶轨迹", "memory")
                line_provider = self.trail_layer.dataProvider()
                line_provider.addAttributes([QgsField("name", QVariant.String)])
                self.trail_layer.updateFields()
                ship_group = root.findGroup("船舶标记") or root.addGroup("船舶标记")
                ship_group.addLayer(self.trail_layer)
            # 设置红色线符号（宽度1.5，实线）
            line_symbol = QgsLineSymbol.createSimple({
                'color': 'red',
                'width': '0.5',
                'style': 'solid'
            })
            self.trail_layer.renderer().setSymbol(line_symbol)

            # 添加轨迹线（连接所有历史点）
            line_feature = QgsFeature()
            line_feature.setGeometry(QgsGeometry.fromPolylineXY(self.ship_positions[:self.current_ship_index + 1]))
            line_feature.setAttributes(["船舶轨迹"])
            self.trail_layer.dataProvider().addFeatures([line_feature])
            self.trail_layer.triggerRepaint()

            # 缩放到当前位置
            self.canvas.setCenter(current_pos)
            self.canvas.refresh()
            self.current_ship_index += 1
        except Exception as e:
            print(f"Excel解析失败: {str(e)}")
    def clear_ship_route(self):
        self.ship_timer.stop()
        root = QgsProject.instance().layerTreeRoot()
        if group := root.findGroup("船舶标记"):
            for layer in group.findLayers():
                QgsProject.instance().removeMapLayer(layer.layerId())
            root.removeChildNode(group)
        if hasattr(self, 'trail_layer'):
            QgsProject.instance().removeMapLayer(self.trail_layer.id())
            del self.trail_layer
        self.ship_layer = None
        self.canvas.refresh()
    # def __clock(self):
    #     # 定时器更新时间
    #     self.ship_timer = QTimer(self)
    #     self.ship_timer.timeout.connect(self.update_ship_position)
    #     self.ship_timer.start(1000)